//  @ Project : GagalPanen
//  @ File Name : plant.cpp
//  @ Date : 3/9/2011
//  @ Author : 
//
//
#include <assert.h>
#include "plant.hpp"
#include "plantconstants.hpp"
#include "plantablecell.hpp"
#include "creatures.hpp"
#include "season.hpp"
#include "gametime.hpp"

Plant::Plant(GameInterface* game, PlantableCell* cell, int plant_id) :
    StandingStillCreature(game, cell),
    happiness_(0),
    plant_id_(plant_id),
    harvest_count_(0),
    total_happiness_(0),
    age_(0),
    form_(kSeedForm)
    {
}

Plant::Plant(GameInterface* game, std::ifstream& is) :
    StandingStillCreature(game, is),
    happiness_(0),
    plant_id_(0),
    harvest_count_(0),
    total_happiness_(0),
    age_(0),
    form_(kSeedForm)
    {
  int form_id;
  is >> happiness_ >> plant_id_ >> harvest_count_ >> total_happiness_ >> age_
          >> form_id;
  form_ = PlantForm(form_id);
}

void Plant::save(std::ofstream& os) {
  StandingStillCreature::save(os);
  os << happiness_ << " " << plant_id_ << " " << harvest_count_ << " " <<
          total_happiness_ << " " << age_ << " " << (int)form_ << std::endl;
}

Plant::~Plant() {}

Fruit* Plant::harvest() {
  assert(isHarvestable());
  ++harvest_count_;
  happiness_ = 0;
  Fruit* ret_fruit = getFruit();

  if (PlantConstants::getPlantHarvestType(plant_id_) == kHarvestOnce) {
    // self-destruction
    game_->getCreatures()->getPlants()->removePlant(this);
  }

  return ret_fruit;
}

bool Plant::isHarvestable() {
  // if mature and ripe
  if (isMature() && !isDead() && 
  getHappiness() >= PlantConstants::getPlantRipeTime(plant_id_, harvest_count_))
  {
    return true;
  }
  return false;
}

void Plant::advanceDay() {
  ++age_;
  PlantableCell* pc = dynamic_cast<PlantableCell* >(getCell());
  std::vector<bool> possible_seasons = Season::getPossibleSeasons(
      PlantConstants::getPlantSeasonMask(getId()));
  if (pc->isWatered() && possible_seasons[game_->getGameTime()->getSeason()]) {
    ++happiness_;
    ++total_happiness_;
    switch (form_) {
      case kSeedForm: {
        if (getHappiness() >= PlantConstants::getPlantMatureTime(plant_id_)) {
          form_ = kMatureForm;
          happiness_ = 0;
          break;
        }
        case kMatureForm: {
          break;
        }
        case kDeadForm: {
          break;
        }
      }
    }
  }
  if (age_ >= PlantConstants::getPlantDeadTime(getId())) {
    form_ = kDeadForm;
  }
  return;
}

void Plant::advanceTime() {
  return;
}

bool Plant::isDead() {
  return form_ == kDeadForm;
}

bool Plant::isMature() {
  return form_ == kMatureForm;
}

bool Plant::isSeed() {
  return form_ == kSeedForm;
}

bool Plant::isSteppable() {
  return form_ == kSeedForm;
}

Fruit* Plant::getFruit() {
  return new Fruit(game_, PlantConstants::getFruitId(plant_id_));
}

int Plant::getHappiness() {
  return happiness_;
}

int Plant::getId() {
  return plant_id_;
}

void Plant::makeDead() {
  age_ = PlantConstants::getPlantDeadTime(getId());
  form_ = kDeadForm;
}
void Plant::makeHarvestable() {
  if (isDead()) {
    // turn back time to its final life and make it harvestable
    age_ = PlantConstants::getPlantDeadTime(getId()) - 1;
  }
  form_ = kMatureForm;
  happiness_ = PlantConstants::getPlantRipeTime(getId(), harvest_count_);
}
void Plant::restartToSeed() {
  age_ = 0;
  happiness_ = 0;
  form_ = kSeedForm;
}

